package cn.zl.common;

import cn.zl.common.config.PropsConfig;
import cn.zl.rtsp.handler.RTSPHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.MultiThreadIoEventLoopGroup;
import io.netty.channel.nio.NioIoHandler;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.rtsp.RtspDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class BaseService {

    private static final Logger logger = LoggerFactory.getLogger(BaseService.class);

    private final String serviceName;

    private EventLoopGroup bossGroup = null;
    private EventLoopGroup workerGroup = null;

    public BaseService(String serviceName) {
        this.serviceName = serviceName;
    }

    public void start() {
        bossGroup = new MultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory());
        workerGroup = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory());
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline()
                                    // 添加netty自带的rtsp消息解析器
                                    .addLast(new RtspDecoder())
                                    // 上一步将消息解析完成之后, 再交给自定义的处理器
                                    .addLast(new RTSPHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            int port = PropsConfig.getInstance().getRtspPort();
            ChannelFuture f = b.bind(port).sync(); // (7)
            logger.info("{}({}) 服务启动成功", serviceName, port);
        } catch (Exception ex) {
            logger.error("{} 服务启动失败, ", serviceName, ex);
        }
    }

}
